/** * */ package net.frontlinesms.plugins.forms.data.repository.hibernate; import java.util.ArrayList; import java.util.Collection; import java.util.List; import net.frontlinesms.data.DuplicateKeyException; import net.frontlinesms.data.domain.Contact; import net.frontlinesms.data.domain.Group; import net.frontlinesms.data.events.EntityDeleteWarning; import net.frontlinesms.data.repository.hibernate.BaseHibernateDao; import net.frontlinesms.events.EventBus; import net.frontlinesms.events.EventObserver; import net.frontlinesms.events.FrontlineEventNotification; import net.frontlinesms.plugins.forms.data.domain.Form; import net.frontlinesms.plugins.forms.data.repository.FormDao; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Restrictions; /** * Hibernate implementation of {@link FormDao} * @author Alex Anderson <alex@frontlinesms.com> * @author Morgan Belkadi <morgan@frontlinesms.com> */ public class HibernateFormDao extends BaseHibernateDao<Form> implements FormDao, EventObserver { //> CONSTRUCTOR /** Create new instance of this DAO */ public HibernateFormDao() { super(Form.class); } public void notify(FrontlineEventNotification notification) { if(notification instanceof EntityDeleteWarning<?>) { EntityDeleteWarning<?> deleteWarning = (EntityDeleteWarning<?>) notification; Object dbEntity = deleteWarning.getDatabaseEntity(); if(dbEntity instanceof Group) { // de-reference any groups which are attached to forms dereferenceGroup((Group) dbEntity); return; } } } public void setEventBus(EventBus eventBus){ eventBus.registerObserver(this); super.setEventBus(eventBus); } /** @see FormDao#getFormsForUser(Contact, Collection) */ @SuppressWarnings("unchecked") public Collection<Form> getFormsForUser(Contact contact, Collection<Integer> currentFormIds) { ArrayList<String> parametersNames = new ArrayList<String>(); parametersNames.add("finalised"); parametersNames.add("contact"); ArrayList<Object> parametersValues = new ArrayList<Object>(); parametersValues.add(true); parametersValues.add(contact); String queryString = "SELECT DISTINCT form" + " FROM Form AS form, GroupMembership AS mem" + " WHERE form." + Form.FIELD_PERMITTED + " = mem.group" + " AND form." + Form.FIELD_FINALISED + " = :finalised" + " AND mem.contact = :contact"; if (currentFormIds.size() > 0) { Long[] longFormIds = new Long[currentFormIds.size()]; int i = 0; for (Integer integer : currentFormIds) longFormIds[i++] = (long)integer; parametersNames.add("ids"); parametersValues.add(longFormIds); queryString += " AND form." + Form.FIELD_ID + " NOT IN (:ids)"; } return super.getHibernateTemplate().findByNamedParam(queryString, parametersNames.toArray(new String[parametersNames.size()]), parametersValues.toArray()); } @SuppressWarnings("unchecked") protected <T> List<T> getList(Class<T> entityClass, String hqlQuery, Object... values) { return this.getHibernateTemplate().find(hqlQuery, values); } /** @see FormDao#getFromMobileId(int) */ public Form getFromId(long id) { DetachedCriteria criteria = super.getCriterion(); criteria.add(Restrictions.eq(Form.FIELD_ID, id)); return super.getUnique(criteria); } /** @see FormDao#saveForm(Form) */ public void saveForm(Form form) { super.saveWithoutDuplicateHandling(form); } /** @see FormDao#updateForm(Form) */ public void updateForm(Form form) { // We're not checking if the form is finalised here, because the group can be modified, even finalised super.updateWithoutDuplicateHandling(form); } /** @see FormDao#deleteForm(Form) */ public void deleteForm(Form form) { super.delete(form); } /** @see FormDao#getAllForms() */ public Collection<Form> getAllForms() { return super.getAll(); } /** @see FormDao#getCount() */ public int getCount() { return super.countAll(); } /** @see FormDao#finaliseForm(Form) */ public void finaliseForm(Form form) throws IllegalStateException { form.finalise(); try { super.update(form); } catch (DuplicateKeyException e) { throw new RuntimeException("This mobile ID has already been set."); } } public void dereferenceGroup(Group group) { DetachedCriteria criteria = super.getCriterion(); Criterion equals = Restrictions.eq(Form.FIELD_PERMITTED, group); Criterion like = Restrictions.like("permittedGroup.path", group.getPath() + Group.PATH_SEPARATOR, MatchMode.START); criteria.add(Restrictions.or(equals, like)); List<Form> forms = getList(criteria); for (Form formWithDereferencedGroup : forms) { formWithDereferencedGroup.setPermittedGroup(null); try { this.update(formWithDereferencedGroup); } catch (DuplicateKeyException e) { // TODO Auto-generated catch block throw new RuntimeException("There was a problem removing the deleted group from its attached form."); } } } }